<template>
  <ul :id="id" class="ztree" v-loading="loading"></ul>
</template>
<script setup lang="ts" name="ZTree">
/* eslint-disable */
// @ts-nocheck
import { nextTick, onMounted, ref, watch } from "vue";

const zNodes = ref([]);
const zNodesVal = ref([]);
const loading = ref(false);

const props = defineProps<{
  id: string;
  api: (params: any) => Promise<any> | any;
  showCode: boolean;
  params: { [key: string]: any }[];
  setting: { [key: string]: any }[];
  zNodes: { [key: string]: any }[];
  enableCheck: boolean;
  checkNodeId: string;
  enableDrag: boolean;
}>();

const emit = defineEmits(["clickDom", "addHoverDom", "removeHoverDom", "onDrop"]);

const beforeDrag = (treeId, treeNodes) => {
  return props.enableDrag;
};

const beforeDrop = (treeId, treeNodes, targetNode, moveType, isCopy) => {
  const zNode = zNodesVal.value.find(item => item.id === treeNodes[0].id);
  if (zNode.parentId === targetNode?.id || !targetNode) return false;
  var zTree = $.fn.zTree.getZTreeObj(treeId);
  zTree.setting.callback.onClick(null, zTree.setting.treeId, treeNodes[0]); //璋冪敤浜嬩欢
  return true;
};

const onDrop = (event, treeId, treeNodes, targetNode, moveType) => {
  const zNode = zNodesVal.value.find(item => item.id === treeNodes[0].id);
  emit("onDrop", { event, treeId, treeNodes, targetNode, moveType, zNode, callback: getZnodes });
};

let setting = {
  view: {
    addHoverDom: (treeId, treeNode) => {
      const zNode = zNodesVal.value.find(item => item.id === treeNode.id);
      emit("addHoverDom", { treeId, treeNode, zNode });
    },
    removeHoverDom: (treeId, treeNode) => {
      const zNode = zNodesVal.value.find(item => item.id === treeNode.id);
      emit("removeHoverDom", { treeId, treeNode, zNode });
    },
    selectedMulti: false
  },
  check: {
    enable: props.enableCheck ?? false
  },
  data: {
    simpleData: {
      enable: true,
      idKey: "id",
      pIdKey: "parentId",
      rootPId: null
    }
  },
  edit: {
    enable: true,
    showRemoveBtn: false,
    showRenameBtn: false
  },
  callback: {
    onClick: (event, treeId, treeNode) => {
      let ids = [treeNode.id];
      nextTick(() => {
        emit("clickDom", { event, treeId, treeNode, ids: getAllChildrenNodes(treeNode, ids) });
      });
    },
    beforeDrag,
    beforeDrop,
    onDrop
  }
};

/**
 * 展开树
 */
const getFlatMapData = (list: any) => {
  let newList = JSON.parse(JSON.stringify(list));
  return newList.flatMap((item: any) => [item, ...(item.children ? getFlatMapData(item.children) : [])]);
};

/**
 * 刷新数据
 */
const refresh = () => {
  let zTree = $.fn.zTree.getZTreeObj(props.id);
  //zTree.expandAll(true);
  let nodes = zTree.getNodes();
  if (nodes.length > 0) {
    zTree.expandNode(nodes[0], true);
    $("#" + nodes[0].tId + "_a").click();
  }
};

/**
 * 获取当前节点子孙节点
 */
const getAllChildrenNodes = (treeNode, ids) => {
  if (treeNode.isParent) {
    var childrenNodes = treeNode.children;
    if (childrenNodes && childrenNodes.length) {
      for (var i = 0; i < childrenNodes.length; i++) {
        ids.push(childrenNodes[i].id);
        ids = getAllChildrenNodes(childrenNodes[i], ids);
      }
    }
  }
  return ids;
};

/**
 * 请求节点树数据
 */
async function init() {
  setting = { ...setting, ...props.setting };
  try {
    zNodesVal.value = getFlatMapData(zNodes.value);
    zNodesVal.value.forEach(item => {
      if (props.showCode) item.name = item.text;
      if (item.children) {
        item.isParent = item.children.length ? "true" : "false";
        delete item.children;
      }
    });
    nextTick(() => {
      $.fn.zTree.init($(`#${props.id}`), setting, zNodesVal.value);
      let zTree = $.fn.zTree.getZTreeObj(props.id);
      //zTree.expandAll(true);
      let nodes = zTree.getNodes();
      zTree.expandNode(nodes[0], true);
      if (nodes.length > 0) {
        let node = zTree.selectNode(nodes[0]);
        if (props.checkNodeId) {
          node = zTree.getNodeByParam("id", props.checkNodeId);
          if (node.isParent) {
            zTree.expandNode(node, true);
          } else {
            zTree.expandNode(zTree.getNodeByParam("id", node.parentId), true);
          }

          $("#" + node.tId + "_a").click();
        } else {
          $("#" + nodes[0].tId + "_a").click();
        }
      }
    });
  } catch (error) {
    console.log(error);
  }
}

/**
 * 请求接口获取节点数据
 */
const getZnodes = async () => {
  try {
    if (props.api) {
      const res = await props.api(props.params);
      zNodes.value = res.data;
    } else {
      zNodes.value = props.zNodes;
    }
    loading.value = false;
    init();
  } catch (error) {
    loading.value = false;
    console.log(error);
  }
};

watch(
  () => props.showCode,
  () => {
    zNodes.value.length && init();
  }
);

watch(
  () => props.zNodes,
  nV => {
    zNodes.value = nV;
    init();
  }
);

onMounted(async () => {
  loading.value = true;
  getZnodes();
});

defineExpose({
  refresh
});
</script>
